package com.nutiteq.tutorial;

import java.io.IOException;

import javax.microedition.lcdui.Canvas;
import javax.microedition.lcdui.Command;
import javax.microedition.lcdui.CommandListener;
import javax.microedition.lcdui.Display;
import javax.microedition.lcdui.Displayable;
import javax.microedition.lcdui.Form;
import javax.microedition.lcdui.Graphics;
import javax.microedition.lcdui.Image;
import javax.microedition.lcdui.StringItem;
import javax.microedition.midlet.MIDlet;

import com.nutiteq.MapItem;
import com.nutiteq.components.Line;
import com.nutiteq.components.LineStyle;
import com.nutiteq.components.OnMapElement;
import com.nutiteq.components.Place;
import com.nutiteq.components.PlaceIcon;
import com.nutiteq.components.WgsPoint;
import com.nutiteq.controls.ControlKeys;
import com.nutiteq.controls.OnScreenZoomControls;
import com.nutiteq.kml.KmlUrlReader;
import com.nutiteq.listeners.OnMapElementListener;
import com.nutiteq.location.LocationMarker;
import com.nutiteq.location.LocationSource;
import com.nutiteq.location.NutiteqLocationMarker;
import com.nutiteq.location.providers.LocationAPIProvider;
import com.nutiteq.log.Log;
import com.nutiteq.maps.CloudMade;
import com.nutiteq.ui.DefaultCursor;
import com.nutiteq.utils.LogForm;
import com.nutiteq.utils.Utils;

public class HelloMap extends MIDlet implements CommandListener, OnMapElementListener {

  private final Form mMainForm;
  private final MapItem mapItem;
  private Image icon;
  private final StringItem message;

  public HelloMap() {
    // create map Item, parameters are:
    // Name of map, License key, midlet object reference, size of map (150x150),
    // initial center location and zoom
    mapItem = new MapItem("Map", "tutorial", this, 300, 150, new WgsPoint(24.764580, 59.437420), 12);

    // define numeric "joystick" controls and select key
    mapItem.defineControlKey(ControlKeys.MOVE_UP_KEY, Canvas.KEY_NUM2);
    mapItem.defineControlKey(ControlKeys.MOVE_DOWN_KEY, Canvas.KEY_NUM8);
    mapItem.defineControlKey(ControlKeys.MOVE_LEFT_KEY, Canvas.KEY_NUM4);
    mapItem.defineControlKey(ControlKeys.MOVE_RIGHT_KEY, Canvas.KEY_NUM6);
    mapItem.defineControlKey(ControlKeys.SELECT_KEY, Canvas.FIRE);

    // add on-screen controls, if phone has pointer
    final Canvas canvas = new Canvas() {
      protected void paint(final Graphics arg0) {
      }
    };
    if (canvas.hasPointerEvents()) {
      mapItem.setOnScreenZoomControls(new OnScreenZoomControls(Utils
          .createImage(OnScreenZoomControls.DEFAULT_ZOOM_IMAGE)));
    } else {
      mapItem.setCursor(new DefaultCursor(0xFFFF0000));
    }

    // add a marker, first load image and then add as a Place
    try {
      icon = Image.createImage("/nutiteq.png");
    } catch (final IOException e) {
    }

    mapItem.addPlace(new Place(1, "Tallinn", icon, 24.764580, 59.437420));

    // draw a line to map (note that this is not Place)
    final WgsPoint[] linePoints = { new WgsPoint(24.76382468302337, 59.44325151314919),
        new WgsPoint(24.76344295658494, 59.4462352840583),
        new WgsPoint(24.76593650384734, 59.44530921763007),
        new WgsPoint(24.76804665483925, 59.44616268729941),
        new WgsPoint(24.76810500478219, 59.443291656657) };

    final Line line = new Line(linePoints, new LineStyle(0xFF00FF00, 1));
    mapItem.addLine(line);

    // define message item to show textual stuff in the Form (useful for GPS
    // location)
    message = new StringItem("", "");

    // define that PlaceListener handler is this midlet class (callback methods
    // are below)
//    mapItem.setOnMapElementListener(this);

    // add Panoramio popular images KML layer, dynamic (as it is based on BBOX)
    // mapItem.addKmlService(new
    // KmlUrlReader("http://www.panoramio.com/panoramio.kml?LANG=en_US.utf8",true));

    // mapItem.addKmlService(new
    // KmlUrlReader("http://lbs.nutiteq.ee/mykmltest.kml",true));
    mapItem.addKmlService(new KmlUrlReader("http://lbs.nutiteq.ee/mpark_tln_trt.kml", true));

    // Now create the form
    mMainForm = new Form("Hello map");
    mMainForm.append(new StringItem(null, "Hello, map!\n"));
    mMainForm.append(mapItem);
    mMainForm.append(message);

    mMainForm.addCommand(new Command("Exit", Command.EXIT, 0));
    mMainForm.setCommandListener(this);

    mMainForm.addCommand(LogForm.SHOW_LOG);
    if (System.getProperty("microedition.location.version") != null) {
      final LocationSource dataSource = new LocationAPIProvider(5000);
      try {
        final Image gpsPresentImage = Image.createImage("/gps_marker.png");
        final Image gpsConnectionLost = Image.createImage("/gps_connection_lost.png");
        final LocationMarker marker = new NutiteqLocationMarker(new PlaceIcon(gpsPresentImage, 4,
            16), new PlaceIcon(gpsConnectionLost, 4, 16), 3000, true);
        dataSource.setLocationMarker(marker);
        mapItem.setLocationSource(dataSource);
      } catch (final IOException e) {
      }
    }
  }

  // callback methods for clicking on marker, center over on ("mouse-over") and
  // center over off
  public void elementClicked(final OnMapElement element) {
    if (!(element instanceof Place)) {
      return;
    }
    final Place p = (Place) element;
    message.setText("Clicked id: " + p.getId() + " place name: " + p.getName());
  }

  public void elementEntered(final OnMapElement element) {
    if (!(element instanceof Place)) {
      return;
    }
    final Place p = (Place) element;
    message.setText("Entered id: " + p.getId() + " place name: " + p.getName());
  }

  public void elementLeft(final OnMapElement element) {
    if (!(element instanceof Place)) {
      return;
    }
    final Place p = (Place) element;
    message.setText("Left id: " + p.getId() + " place name: " + p.getName());
  }

  public void startApp() {
    Log.enableAll();
    Display.getDisplay(this).setCurrent(mMainForm);
    // Finally, start mapping process (downloading)
    mapItem.startMapping();
  }

  public void pauseApp() {
  }

  public void destroyApp(final boolean unconditional) {
  }

  public void commandAction(final Command c, final Displayable s) {
    if (c == LogForm.SHOW_LOG) {
      Display.getDisplay(this).setCurrent(new LogForm(mapItem, this, mMainForm));
      return;
    }
    mapItem.stopMapping();
    notifyDestroyed();
  }

  // method to show string as one form element
  public void displayString(final String string) {
    message.setText(string);
  }

  public void placeHidden(final Place p) {
  }

  public void placeVisible(final Place p) {
  }

}